package com.graduation.springbootinit.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.graduation.springbootinit.common.ErrorCode;
import com.graduation.springbootinit.exception.BusinessException;
import com.graduation.springbootinit.mapper.QuizChallengeMapper;
import com.graduation.springbootinit.mapper.QuizQuestionMapper;
import com.graduation.springbootinit.mapper.QuizRecordMapper;
import com.graduation.springbootinit.model.entity.ActivityPart.QuizChallenge;
import com.graduation.springbootinit.model.entity.ActivityPart.QuizQuestion;
import com.graduation.springbootinit.model.entity.ActivityPart.QuizRecord;
import com.graduation.springbootinit.model.vo.QuizQuestionVO;
import com.graduation.springbootinit.model.request.QuizSubmitRequest;
import com.graduation.springbootinit.service.QuizChallengeService;
import com.graduation.springbootinit.service.UserPointsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.stream.Collectors;
import java.util.ArrayList;

@Service
public class QuizChallengeServiceImpl extends ServiceImpl<QuizChallengeMapper, QuizChallenge>
        implements QuizChallengeService {

    @Resource
    private QuizQuestionMapper questionMapper;
    
    @Resource
    private QuizRecordMapper recordMapper;
    
    @Resource
    private UserPointsService userPointsService;

    @Override
    public void createChallenge(QuizChallenge challenge) {
        // 验证参数
        if (challenge.getTitle() == null || challenge.getTitle().isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "标题不能为空");
        }
        if (challenge.getPassScore() == null || challenge.getPassScore() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "及格分数必须大于0");
        }
        
        // 设置默认值
        if (challenge.getStatus() == null) {
            challenge.setStatus(1); // 默认进行中
        }
        if (challenge.getParticipationPoints() == null) {
            challenge.setParticipationPoints(0);
        }
        
        save(challenge);
    }

    @Override
    public void addQuestion(QuizQuestion question) {
        if (question.getQuestionContent() == null || question.getQuestionContent().isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "题目内容不能为空");
        }
        if (question.getCorrectAnswer() == null || !question.getCorrectAnswer().matches("[A-D]")) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "正确答案必须是A-D");
        }
        
        questionMapper.insert(question);
    }

    @Override
    public List<QuizQuestionVO> getChallengeQuestions(Long challengeId) {
        List<QuizQuestion> questions = questionMapper.selectByChallengeId(challengeId);
        return questions.stream().map(question -> {
            QuizQuestionVO vo = new QuizQuestionVO();
            vo.setId(question.getId());
            vo.setQuestionContent(question.getQuestionContent());
            vo.setOptionA(question.getOptionA());
            vo.setOptionB(question.getOptionB());
            vo.setOptionC(question.getOptionC());
            vo.setOptionD(question.getOptionD());
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public QuizRecord submitAnswers(Long userId, Long challengeId, List<QuizSubmitRequest.AnswerRecord> answers) {
        // 检查挑战状态
        QuizChallenge challenge = getById(challengeId);
        if (challenge == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "挑战不存在");
        }
        if (challenge.getStatus() != 1) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "挑战未在进行中");
        }
        
        // 检查是否已经参与过
        QueryWrapper<QuizRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId).eq("challenge_id", challengeId);
        if (recordMapper.selectCount(queryWrapper) > 0) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "您已经参与过此挑战");
        }

        // 获取所有题目
        Map<Long, QuizQuestion> questionMap = questionMapper.selectByChallengeId(challengeId)
                .stream()
                .collect(Collectors.toMap(QuizQuestion::getId, q -> q));
        
        // 计算得分
        int totalScore = 0;
        int correctCount = 0;
        List<String> answerList = new ArrayList<>();
        
        for (QuizSubmitRequest.AnswerRecord answer : answers) {
            QuizQuestion question = questionMap.get(answer.getQuestionId());
            if (question == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "题目不存在");
            }
            answerList.add(answer.getAnswer());
            if (answer.getAnswer().equals(question.getCorrectAnswer())) {
                totalScore += question.getScore();
                correctCount++;
            }
        }
        
        // 如果达到及格分数，发放参与积分
        if (totalScore >= challenge.getPassScore()) {
            userPointsService.addPoints(userId, challenge.getParticipationPoints(), 
                    "完成答题挑战[" + challenge.getTitle() + "]及格奖励");
        }
        
        // 创建答题记录
        QuizRecord record = new QuizRecord();
        record.setUserId(userId);
        record.setChallengeId(challengeId);
        record.setAnswers(String.join(",", answerList));
        record.setTotalScore(totalScore);
        record.setCorrectCount(correctCount);
        recordMapper.insert(record);
        
        return record;
    }

    @Override
    public Page<QuizChallenge> getOngoingChallenges(int pageNum, int pageSize) {
        Page<QuizChallenge> page = new Page<>(pageNum, pageSize);
        return baseMapper.selectOngoingChallenges(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void endChallengeAndReward(Long challengeId) {
        QuizChallenge challenge = getById(challengeId);
        if (challenge == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "挑战不存在");
        }
        if (challenge.getStatus() != 1) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "挑战未在进行中");
        }
        
        // 检查是否到达结束时间
        if (LocalDateTime.now().isBefore(challenge.getEndTime())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "挑战还未到结束时间");
        }
        
        // 获取所有参与记录并按分数排序
        QueryWrapper<QuizRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("challenge_id", challengeId)
                .orderByDesc("total_score", "correct_count")
                .orderByAsc("created_at");
        List<QuizRecord> allRecords = recordMapper.selectList(queryWrapper);
        
        // 发放奖励
        for (int i = 0; i < allRecords.size(); i++) {
            QuizRecord record = allRecords.get(i);
            int points = 0;
            String rankDesc = "";
            
            if (i == 0 && record.getTotalScore() >= challenge.getPassScore()) {
                points = challenge.getFirstPrize();
                rankDesc = "一等奖";
            } else if (i == 1 && record.getTotalScore() >= challenge.getPassScore()) {
                points = challenge.getSecondPrize();
                rankDesc = "二等奖";
            } else if (i == 2 && record.getTotalScore() >= challenge.getPassScore()) {
                points = challenge.getThirdPrize();
                rankDesc = "三等奖";
            }
            
            if (points > 0) {
                // 更新排名和积分
                record.setRanking(i + 1);
                record.setPointsReceived(points);
                recordMapper.updateRankAndPoints(record.getId(), i + 1, points);
                
                // 给用户添加积分
                userPointsService.addPoints(record.getUserId(), points, 
                        "获得答题挑战[" + challenge.getTitle() + "]" + rankDesc);
            }
        }
        
        // 更新挑战状态
        challenge.setStatus(2);
        updateById(challenge);
    }

    @Override
    public List<QuizRecord> getUserQuizHistory(Long userId) {
        return recordMapper.selectUserQuizHistory(userId);
    }

    @Override
    public Map<String, Object> getChallengeStats(Long challengeId) {
        QuizChallenge challenge = getById(challengeId);
        if (challenge == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "挑战不存在");
        }
        
        QueryWrapper<QuizRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("challenge_id", challengeId);
        List<QuizRecord> records = recordMapper.selectList(queryWrapper);
        
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalParticipants", records.size());
        stats.put("averageScore", records.stream()
                .mapToInt(QuizRecord::getTotalScore)
                .average()
                .orElse(0.0));
        stats.put("passCount", records.stream()
                .filter(r -> r.getTotalScore() >= challenge.getPassScore())
                .count());
        stats.put("highestScore", records.stream()
                .mapToInt(QuizRecord::getTotalScore)
                .max()
                .orElse(0));
        stats.put("lowestScore", records.stream()
                .mapToInt(QuizRecord::getTotalScore)
                .min()
                .orElse(0));
        
        return stats;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addQuestionBatch(Long challengeId, List<QuizQuestion> questions) {
        // 验证挑战是否存在
        QuizChallenge challenge = getById(challengeId);
        if (challenge == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "挑战不存在");
        }
        
        // 验证题目
        for (QuizQuestion question : questions) {
            if (question.getQuestionContent() == null || question.getQuestionContent().isEmpty()) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "题目内容不能为空");
            }
            if (question.getCorrectAnswer() == null || !question.getCorrectAnswer().matches("[A-D]")) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "正确答案必须是A-D");
            }
            if (question.getScore() == null || question.getScore() <= 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "分值必须大于0");
            }
            question.setChallengeId(challengeId);
        }
        
        // 批量保存
        questionMapper.insertBatch(questions);
    }
} 